import 'dart:convert';
import 'dart:core';
import 'package:calf_account/utils/file_util.dart';
import 'package:calf_account/utils/random_util.dart';
import 'package:crypto/crypto.dart';
import 'package:encrypt/encrypt.dart' as encrypt;
import 'package:encrypt/encrypt.dart';

class CalfSecurity {
  final String _securityPath = "/document/calf_sign.d";

  List<int> toSha256(String key, String data) {
    return Hmac(sha256, utf8.encode(key)).convert(utf8.encode(data)).bytes;
  }

  ///加解密策略
  ///1. 秘钥：【主密码】派生 + 随机256位盐值【SHA256二进制】文件
  ///2. 所有关键数据都应该加密
  ///3. 加密采用AES64 对称性加密方式
  ///4. 用户应当保存好【主密码】和 【MD5文本】,解密缺一不可

  /// 秘钥文件是否存在
  Future<bool> signExists() async {
    return FileUtil().exists(_securityPath);
  }

  /// 随机256位盐值【SHA256二进制】文件
  Future<String> createSignFile() async {
    var key = RandomUtil().randomPassword(256);
    var data = RandomUtil().randomPassword(256);
    //写入秘钥文件
    String filePath =
        await FileUtil().write(_securityPath, toSha256(key, data));
    return filePath;
  }

  /// 读取SHA256签名秘钥
  Future<String> _readSignFile() async {
    var content = await FileUtil().read(_securityPath);
    if (content != null) {
      return utf8.decode(content);
    } else {
      throw Exception("秘钥文件不存在!");
    }
  }

  /// AES加密
  String aesEncrypt(String key, String data) {
    Key ek = encrypt.Key.fromUtf8(key);
    var encryptor =
        encrypt.Encrypter(encrypt.AES(ek, mode: encrypt.AESMode.ecb));
    return encryptor.encrypt(data).base64;
  }

  /// AES解密
  String aesDecrypt(String key, String data) {
    Key ek = encrypt.Key.fromUtf8(key);
    var encryptor =
        encrypt.Encrypter(encrypt.AES(ek, mode: encrypt.AESMode.ecb));
    return encryptor.decrypt64(data);
  }

  ///-----------------------业务方法---------------------------------------------
  ///  数据使用对称秘钥加密
  Future<String> encryptData(String mainPassword, String data) async {
    String sign = await _readSignFile();
    return aesEncrypt(utf8.decode(toSha256(sign, mainPassword)), data);
  }

  ///  数据使用对称秘钥解密
  Future<String> decryptData(String mainPassword, String data) async {
    String sign = await _readSignFile();
    return aesDecrypt(utf8.decode(toSha256(sign, mainPassword)), data);
  }

  /// 导入签名秘钥
  void importSignFile(String data) {
    FileUtil().write(_securityPath, utf8.encode(data));
  }

  /// 导出签名秘钥
  Future<String> exportSignFile(String data) async {
    return await _readSignFile();
  }
}
